<?php

namespace app\client\services;


use app\admin\model\CustomerLoginLogModel;
use app\admin\model\CustomerModel;
use app\admin\model\LoginLogModel;
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
use Firebase\JWT\SignatureInvalidException;
use think\facade\Cache;

class CustomerService
{
    protected static $key='zpf0321!@$!';

    /**
     * 登录操作生成token
     * @param $openid 用户平台唯一识别标识
     * @param $platform 平台
     * @param $avatar 头像
     * @param $username 用户名
     * @param $unionid 唯一标识unionid
     * @param $sharecode 推广码
     * @return array
     * @throws \Psr\SimpleCache\InvalidArgumentException
     */
    public static function login($openid,$platform,$avatar,$username,$unionid,$sharecode='')
    {
        $clientInfo = self::verifyLogin($openid, $platform,$avatar,$username,$unionid,$sharecode);
        $returnAdminInfo = [
            "id" => $clientInfo->id,
            'unionid'=>$clientInfo->unionid,
            "openid" => $clientInfo->openid,
            'balance'=>$clientInfo->balance
        ];
        //缓存用户数据
        Cache::store("clientInfo")->set("ADMIN_USERINFO_" . $clientInfo->id, $returnAdminInfo);
        $tokenInfo = self::createToken($clientInfo->id);
        return [
            'token' => $tokenInfo??"",
            'admin_info' => $returnAdminInfo??[],
        ];
    }

    public static function my($customerId){
        api_return(200,'',[
            'balance'=>CustomerModel::find($customerId)->balance
        ]);
    }

    /**
     * 登录验证
     * @param string $openid 平台openid
     * @param string $platform wx,dy,zfb
     * @return CustomerModel|array|mixed|\think\Model|null
     */
    protected static function verifyLogin(string $openid, string $platform,$avatar,$username,$unionid,$sharecode='')
    {
        $customerInfo = CustomerModel::getCustomerInfoByOpenid($openid,$platform);
        if (!$customerInfo) {
            $customerId= CustomerModel::create([
                'login_time'=>date('Y-m-d H:i:s'),
                'ip'=> app('request')->ip(),
                'login_count'=>1,
                'avatar'=>$avatar,
                'username'=>$username,
                'openid'=>$openid,
                'platform'=>$platform,
                'unionid'=>$unionid,
                'sharecode'=>$sharecode
            ]);
            CustomerLoginLogModel::insertLog($customerId->id,$sharecode);
            return $customerId;
        }else {
            CustomerLoginLogModel::insertLog($customerInfo->id,$customerInfo->sharecode);
            $customerInfo->login_time = date('Y-m-d H:i:s');
            $customerInfo->ip = app('request')->ip();     //获取IP地址
            $customerInfo->login_count++;
            $customerInfo->avatar = $avatar;
            $customerInfo->username = $username;
            $customerInfo->save();
//            event(new UserLogin($openid, 200, 1));
            return $customerInfo;
        }
    }

    /**
     * 创建token
     * @param int $uid
     * @return string
     */
    public static function createToken(int $uid)
    {
        $time = time(); //签发时间
        $expire = $time + env("LOGIN.LOGIN_EXPIRE_TIMEOUT"); //过期时间
        $token = array(
            "customer_id" => $uid,
            "iss" => "yijiumei",//签发组织
            "aud" => "zpf",
            "iat" => $time,
            "nbf" => $time,
            "exp" => $time + env("LOGIN.LOGIN_EXPIRE_TIMEOUT") //过期时间
        );
        return JWT::encode($token, self::$key, "HS256");
    }

    /**
     * 解析token
     * @param string $jwt
     * @return bool
     */
    public static function parseToken(string $jwt)
    {
        try {
//            JWT::$leeway = 10;
            $jwtAuth = json_encode(JWT::decode($jwt, new Key(self::$key, "HS256")));
            $authInfo = json_decode($jwtAuth, true);
            $result = false;
            if (!empty($authInfo['customer_id'])) {
                $result = $authInfo['customer_id'];
            }
            return $result;
        } catch (\Firebase\JWT\ExpiredException $e) {
            api_return(20002, "登录超时，请重新登录".$e->getMessage());
            exit;
        } catch (SignatureInvalidException $e) {
            api_return(20002, $e->getMessage());
            exit;
        } catch (\Exception $e) {
            api_return(20002, $e->getMessage());
            exit;
        }
    }
}
